import configTool from '../../../com/configTool';
import initDB from '../Util/initDB';
import axios from 'axios';
import crypto from 'crypto';
import readFromDB from '../Util/readFromDB';
import saveToDB from '../Util/saveToDB';
import DBConnectTool from '../../../com/DBTool/DBConnectTool';


let Loading = true;
const DBName = 'tile.googleapis.com';
const Cesium = require('cesium/Build/Cesium/index.cjs');
const defaultAccessToken = Cesium.Ion.defaultAccessToken;

type ResponseType = | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream';

let key = '';
let session = '';

async function getWallData(url: string, responseType: ResponseType = 'json'): Promise<any> {
    return new Promise((resolve, reject) => {
        axios
            .get(url, {
                responseType: responseType,
                proxy: {
                    protocol: 'http',
                    host: '127.0.0.1',
                    port: 7890
                }
            })
            .then(e => resolve(e.data))
            .catch(e => resolve(null));
    });
}

let Google3DTiles = {
    async init() {
        if (Loading) {
            Loading = false;
            await configTool.init();
            configTool.preservableONDB() && await initDB(DBName);
        }
    },
    async getRootJson() {
        await this.init();

        await initDB(DBName);
        await DBConnectTool.openDB(DBName);

        const endpointUrl = 'https://api.cesium.com/v1/assets/2275207/endpoint?access_token=' + defaultAccessToken;
        try {
            const authority = await fetch(endpointUrl).then(e => e.json());
            const rootUrl = authority.options.url;

            // 模型数据的外层 Root JSON，不包含实际数据，仅包含鉴权信息
            const rootJson = await getWallData(rootUrl, 'json');
            let tileSetRootRelativeUri = rootJson.root.children[0].children[0].content.uri;
            key = new URL(rootUrl).searchParams.get('key') || '';


            // 倾斜模型的实际 Root Url
            const tileSetRootUri = `https://tile.googleapis.com${tileSetRootRelativeUri}&key=${key}`;
            session = new URL(tileSetRootUri).searchParams.get('session') || '';
            tileSetRootRelativeUri = tileSetRootRelativeUri.split('?').shift();


            // 倾斜模型的实际 Root JSON
            const {json: tileSetRoot} = await this.getJson(tileSetRootRelativeUri);

            return {key, session, tileSetRoot};
        } catch (e) {
            console.error('获取 GooglePhotorealistic3DTileSet 失败');
            return null;
        }
    },
    async hasFile(uri: string) {

        const dbPath = uri.replaceAll('/', '\\');
        const dbTool = await DBConnectTool.openDB(DBName);
        if (await dbTool.getFileByFullPath(dbPath)) {
            return true;
        } else {
            return false;
        }
    },
    async getJson(uri: string, needSaveToDB = true) {
        const {buffer, dataSource} = await this.getBuffer(uri, needSaveToDB, true);
        return {json: JSON.parse(buffer.toString()), dataSource};
    },
    async getBuffer(uri: string, needSaveToDB = true, needCompress = false) {
        const dbPath = uri.replaceAll('/', '\\');
        let [err, buffer, dataSource] = await readFromDB({DBName: DBName, relativePath: dbPath});

        if (!buffer) {
            buffer = await getWallData(`https://tile.googleapis.com${uri}?session=${session}&key=${key}`, 'arraybuffer');
            dataSource = 'Net';

            if (needSaveToDB) {
                // 存入缓存文件
                const md5Str = crypto.createHash('md5').update(buffer).digest('hex');
                if (md5Str) {
                    saveToDB({DBName: DBName, relativePath: dbPath, buffer}, needCompress).then();
                }
            }
        }

        return {err, buffer, dataSource};
    }
};

export default Google3DTiles;
